package group2.core.database.impl;

import group2.core.database.IJpaCtrl;
import group2.core.database.NonexistentEntityException;
import group2.core.entities.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.transaction.UserTransaction;

/**
 * Manages the database connection for Users.
 * 
 * @author cnilsson
 */
public class CamelUserJpaCtrl implements IJpaCtrl<CamelUser> {

    // UserTransaction not used in non container (i.e. for now)
    private final UserTransaction utx;
    // Get from Database
    private final EntityManagerFactory emf;

    public CamelUserJpaCtrl(UserTransaction utx, EntityManagerFactory emf) {
        this.utx = utx;
        this.emf = emf;
    }

    @Override
    public void create(CamelUser t) {
        EntityManager em = getEntityManager();
        try {
            em.getTransaction().begin();
            em.persist(t);
            em.getTransaction().commit();
        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", e);
            em.getTransaction().rollback();
        } finally {
            em.close();
        }
    }

    @Override
    public void destroy(Long id) throws NonexistentEntityException {
        EntityManager em = getEntityManager();
        try {
            em.getTransaction().begin();
            CamelUser cU = em.find(CamelUser.class, id);

            List<Comment> deleteList = getDeleteCommentList(cU);
            for (Comment c : deleteList) {
                if (c.getCommentAuthor().getId() == cU.getId()) {
                    c.getPost().removeComment(c);
                } else {
                    c.getCommentAuthor().removeComment(c);
                }
            }
            em.remove(cU);
            em.getTransaction().commit();
        } finally {
            em.close();
        }
    }
    
    private List<Comment> getDeleteCommentList(CamelUser user) {
        List<Post> posts = user.getPosts();
        ArrayList<Comment> returnList = new ArrayList();
        returnList.addAll(user.getComments());
        for (Post currentPost : posts) {
            returnList.addAll(currentPost.getComments());
        }
        return returnList;
    }

    @Override
    public void edit(CamelUser t) throws NonexistentEntityException, Exception {
        EntityManager em = getEntityManager();
        try {
            em.getTransaction().begin();
            CamelUser cU = em.find(CamelUser.class, t.getId());
            cU.setUserName(t.getUserName());
            cU.setPassword(t.getPassword());
            cU.setFirstName(t.getFirstName());
            cU.setLastName(t.getLastName());
            cU.setEmail(t.getEmail());
            cU.setUserLevel(t.getUserLevel());
            em.getTransaction().commit();
        } finally {
            em.close();
        }
    }

    @Override
    public List<CamelUser> findEntities() {
        EntityManager em = getEntityManager();
        List<CamelUser> list = null;

        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<CamelUser> query = builder.createQuery(CamelUser.class);
        Root<CamelUser> cU = query.from(CamelUser.class);
        query.select(cU);
        TypedQuery<CamelUser> q = em.createQuery(query);
        list = q.getResultList();
        if (list == null) {
            list = new ArrayList();
        }
        return list;
    }

    @Override
    public List<CamelUser> findEntities(int maxResults, int firstResult) {
        List<CamelUser> list = findEntities();

        if (maxResults >= list.size()) {
            maxResults = list.size();
        }

        if (firstResult + maxResults > list.size()) {
            firstResult = list.size() - maxResults;
        }

        return list.subList(firstResult, firstResult + maxResults);
    }

    @Override
    public CamelUser findEntity(Long id) {
        CamelUser cU = null;
        EntityManager em = getEntityManager();
        try {
            em.getTransaction().begin();
            cU = em.find(CamelUser.class, id);
            em.getTransaction().commit();
        } finally {
            em.close();
            return cU;
        }
    }

    @Override
    public int getEntityCount() {
        return findEntities().size();
    }

    @Override
    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

}
